package com.piece.core.db.util;

import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.object.BeanUtil;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 数据库查询工具类
 */
public class QueryUtil {

    /**
     * 生成sql查询条件
     *
     * @param sql            sql语句
     * @param alias          查询别名
     * @param condition      转换条件,Q_字段名称_类别_条件_关联关系<br>
     *                       Q: 固定查询标识<br>
     *                       字段名称:  属性名称<br>
     *                       类别:  S:string、 L:long、 DOU:double、 INT:int、 BD:BigDecimal、 FL:float、 SH:short、 D:date<br>
     *                       条件:  LT:<、 GT:>、 EQ:=、 LE:<=、 GE:>=、 LK:like、EMP:empty、 NEMP:not empty、
     *                       NULL:null、 NNULL:not null、IN:in、 NIN:not in、 NEQ:!=<br>
     *                       关联关系: AND、OR，默认为AND
     * @param conditionValue 转换值
     * @param convertColumn  是否转换列名
     */
    public static String generateCondition(String sql, String alias, Class entityClass, Map<String, Object> condition, List<Object> conditionValue, boolean convertColumn) {
        return generateCondition(sql, alias, entityClass, condition, conditionValue, convertColumn, true);
    }

    /**
     * 生成sql查询条件
     *
     * @param sql            sql语句
     * @param alias          查询别名
     * @param condition      转换条件,Q_字段名称_类别_条件_关联关系<br>
     *                       Q: 固定查询标识<br>
     *                       字段名称:  属性名称<br>
     *                       类别:  S:string、 L:long、 DOU:double、 INT:int、 BD:BigDecimal、 FL:float、 SH:short、 D:date<br>
     *                       条件:  LT:<、 GT:>、 EQ:=、 LE:<=、 GE:>=、 LK:like、EMP:empty、 NEMP:not empty、
     *                       NULL:null、 NNULL:not null、IN:in、 NIN:not in、 NEQ:!=<br>
     *                       关联关系: AND、OR，默认为AND
     * @param conditionValue 转换值
     * @param convertColumn  是否转换列名
     * @param usePosition    是否使用占位符
     */
    public static String generateCondition(String sql, String alias, Class entityClass, Map<String, Object> condition, List<Object> conditionValue, boolean convertColumn, boolean usePosition) {
        if (null == condition) {
            return sql;
        }

        Iterator iterator = condition.entrySet().iterator();
        String name = null, column = null;
        Object value = null;
        String where = "";
        int position = conditionValue.size();
        String alias_temp = null == alias ? "" : (alias + ".");

        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            name = (String) entry.getKey();
            value = entry.getValue();

            if (!name.startsWith("Q_")) {
                column = name;
                if (convertColumn) {
                    column = BeanUtil.getColumnName(entityClass, column);
                }
                if (usePosition) {
                    where += "and " + alias_temp + column + " = ?" + position++ + " ";
                } else {
                    where += "and " + alias_temp + column + " = ? ";
                }
                conditionValue.add(value);
            } else {
                column = name.split("_")[1];
                if (convertColumn) {
                    column = BeanUtil.getColumnName(entityClass, column);
                }

                where += Convert.invertFormat(column, name, value, conditionValue, alias, usePosition);
                if (usePosition) {
                    position++;
                }
            }
        }

        if (where.length() > 0) {
            sql = sql.trim();
            if (sql.toUpperCase().indexOf("WHERE") == -1) {
                if (where.toUpperCase().startsWith("AND")) {
                    where = where.substring(3);
                } else if (where.toUpperCase().startsWith("OR")) {
                    where = where.substring(2);
                }
                where = " where " + where;
            } else if (sql.toUpperCase().endsWith("WHERE")) {
                if (where.toUpperCase().startsWith("AND")) {
                    where = where.substring(3);
                } else if (where.toUpperCase().startsWith("OR")) {
                    where = where.substring(2);
                }
                where = " " + where;
            }
        }

        sql = sql + " " + where;
        return sql;
    }
}
